﻿#ifndef __LIBCARD_H_
#define __LIBCARD_H_

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termio.h>
#include <sys/signal.h>
#include <pthread.h>
#include <time.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <semaphore.h>
#include <sys/socket.h>
#include <dirent.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <stdbool.h>
#include <assert.h>
#include "database/database.h"

#ifdef __cplusplus
extern "C"{
#endif

#define NW_CARD

typedef unsigned char		uint8;
typedef unsigned short		uint16;
typedef unsigned int		uint32;

/*区域卡类型*/
enum AreaCardType{
    CARD_COMMON_PERSONAL_STORAGE_VALUE = 0x0300,	//普通个人储值卡
    CARD_COMMON_PERSONAL_MONTH = 0x0600,	//普通个人月票卡
    CARD_MEMENTO_STORAGE_VALUE =0x1300,		//纪念储值卡
    CARD_ELDER_STORAGE_VALUE_1 = 0x4301,		//长者储值卡
    CARD_ELDER_STORAGE_VALUE_2	= 0x4302,		//长者储值卡
    CARD_STUDENT = 0x5600,		//学生卡
    CARD_BUS_EMPLOYEES = 0x6300,		//公交企业员工卡
    CARD_LOW_INSURANCE = 0x7000,		//低保卡
    CARD_MILITARY_GENUS = 0x7100,		//军属卡（优抚卡）
    CARD_SERIOUS_DEFORMED_MAN = 0x7201,		//重度残疾人卡
    CARD_THREE_FOUR_LEVEL_DEFORMED_MAN = 0x7202,		//三、四级残疾人卡
    CARD_BUS_SUPERVISE_OR_PUBLIC_ORDER = 0x8400,		//公交监督卡及治安值勤卡
};

/*区域代码说明*/
enum AreaCode{
    AREA_WHOLE_PROVINCE = 0,		//全省
    AREA_GUANG_ZHOU = 1,		//广州
    AREA_FO_SHAN = 11,		//佛山
    AREA_SHEN_ZHEN = 20,	//深圳
    AREA_ZHU_HAI = 25,		//珠海
    AREA_SHAN_WEI = 30,		//汕尾
    AREA_JIANG_MEN = 35,		//江门
    AREA_ZHAO_QING = 40,	//肇庆
    AREA_ZHONG_SHAN = 42,	//中山
    AREA_DONG_GUAN = 45,	//东莞
    AREA_HUI_ZHOU = 48,		//惠州
    AREA_ZHAN_JIANG = 50,		//湛江
    AREA_SHAN_TOU = 51,		//汕头
    AREA_SHAO_GUAN = 52,		//韶关
    AREA_HE_YUAN = 53,	//河源
    AREA_YANGJIANG = 54, //阳江
    AREA_QING_YUAN = 55,	//清远
    AREA_MAO_MING = 56,	//茂名
    AREA_MEI_ZHOU = 57,	//梅州
    AREA_CHAO_ZHOU = 58,	//潮州
    AREA_JIE_YANG = 59,	//揭阳
    AREA_YUN_FU = 60,	//云浮
};

typedef struct
{
    char name[512];
    uint32 baud;
    uint8 data_bits;
    uint8 parity;
    uint8 stop_bits;
    uint16 recv_delay;
    uint8 dev_addr;
    uint8 VoltageLevel;
}card_uart_para;


typedef struct
{
    card_uart_para  com;   //串口参数
    char cardtype;     //卡类型
    char auto_find;     //自动寻卡 0 手动寻卡 1 自动寻卡
    char max_lockcount;  //最大灰锁次数
    unsigned char pass[3];

    //以上信息由外部填写，供动态库调用
    //以下信息由本库填写，供外部调用
    char errcode; //错误代码 0 通信正常，1 通信异常
    //以下信息在自动寻卡方式下才填写
    unsigned char  UIDLen;  //卡序列号长度
    char         cardUID[64]; //卡序列号
    char         cmd1[8]; //卡返回命令1
    char         cmd2[8]; //卡返回命令2
    char         cmd3[4]; //卡返回命令3
    short        cardNUM[8]; //卡号
    unsigned int  available_money;//卡余额
    char 		ver;//密匙版本号
    char 		tag;//算法标识
    int 			rand;//随机数
    int 			mac;//mac地址

}rf_card;

/*本结构为羊城通读卡器消费处理返回信息*/
typedef struct{
    unsigned char cur_tr_devNum[6];//BCD 终端机编号  本次交易设备编号
    unsigned char terminal_sernum[4];//脱机交易流水号 终端交易序号
    unsigned char cur_trade_date[7];//BCD  本次交易日期时间
    unsigned char logic_card_Num[8];//逻辑卡号
    unsigned char phy_card_Num[8];//物理卡号
    unsigned int real_money;//实际交易金额 交易金额 以分为单位
    unsigned int org_money;//原交易金额   票价 以分为单位
    unsigned int cur_balance;// 本次余额 以分为单位
    unsigned char tr_type;//交易类型
    unsigned char attach_tr_type;//附加交易类型
    unsigned short recharge_count;//充值交易计数
    unsigned short consum_count;//消费交易计数
    unsigned char addup_mon[2];//累计门槛月份
    unsigned char bus_count;//公交门槛计数
    unsigned char subway_count;//地铁门槛计数
    unsigned char  conn_count;//联乘门槛计数
    unsigned char cur_tr_enter_devNum[6];//BCD  本次交易入口设备编号
    unsigned char cur_tr_enter_date[7];//BCD  本次交易入口日期时间
    unsigned char last_tr_devNum[6];//BCD 上次交易设备编号
    unsigned char last_tr_time[4];//BCD  上次交易日期时间MMDDHHMM (24小时制)
    unsigned char area_code;//BCD 区域代码
    unsigned short area_card_type;//BCD 区域卡类型
    unsigned  char area_son_code;//BCD 区域子码
    unsigned char TAC[4];//交易认证码 该域在消费预处理时，返回为4个字节的0x0
}yct_rf_consum_card;

/*本结构为羊城通读卡器未完整消费处理信息结构*/
//typedef struct {
//	unsigned char logic_cardNum[8];//逻辑卡号
//	unsigned char cardNum[8];//物理卡号
//	int ticket_trade_count;//票卡交易计数器   未完整交易记录的“票卡消费交易计数”。
//	int trade_money;//交易金额  未完整交易记录的“本次交易的交易金额”
//	int balance;//本次余额  未完整交易记录的“ 本次余额”
//}yct_incomplete_trade;

//初始化函数，pcard指向一个rf_card结构， plock指向pthread_mutex_t互斥量,         指向sem_t信号量,在检测到刷卡时置位。
int protocol_card_init(void * pcard, void *plock, void *psem); //返回0成功，1 失败

//关闭函数，释放资源
int protocol_card_close();//返回0成功，1 失败

//激活卡函数，delaytime 等待时间，cardtype 返回的卡类型，UIDLen返回的卡号长度，cardUID指向一个32字节大小的内存，用于存储返回的卡号。
int protocol_enabled_card(short delaytime, char *cardtype, unsigned char *UIDLen, char * cardUID); //返回0成功，1 失败

/*
 * 作用:读卡，money 返回卡余额，locknum 返回灰锁次数。
 * 每次消费前都需要读卡，确定卡号
 * 返回0成功，1 失败
 */
int protocol_read_card(float *money, char *locknum);

/*
 * 作用：锁卡，并获取当前卡片的交易信息   下发充电指令之前需要调用该函数锁卡
*预消费  org_money原交易金额 (以分为单位)   real_money实际交易金额 (以分为单位) 由UI填充
*预消费  card_info该形参由读卡器进行填充，该指针不能为空或野指针，读卡器填充
*预消费  返回成功时，返回失败时禁止充电，返回成功允许充电；  返回失败时需要提示刷卡结算，解卡
*预消费   成功返回0; 填充的card_info需UI交给主控，将羊城通信息上报后台
*预消费  失败原因 1(钱包余额不足)  2(卡片超出有效期)  3(未感应到卡片)  4(卡片已锁)   5读卡器故障 其他刷卡返回失败原因
**/
int protocol_yct_card_preconsume(int org_money, int real_money, yct_rf_consum_card* card_info);

/*
 * 作用：扣费，解卡  ； 充电结束结算，充电启动失败均需要调用该接口进行解卡扣费
 * 结算交易  org_money原交易金额  (以分为单位)   real_money实际交易金额 (以分为单位),       由UI负责填充这2个参数，供读卡器使用
 * card_info  该形参由读卡器进行填充，该指针不能为空或野指针
 *  成功返回0； 填充的card_info需UI交给主控，将羊城通信息上报后台
 * 失败原因 1(钱包余额不足)  2(卡片超出有效期)  3(未感应到卡片)   5读卡器故障  其他刷卡返回失败原因  如果结算失败，应提示说明
 * */
int protocol_yct_card_settle_accounts(int org_money, int real_mone,yct_rf_consum_card* card_info);


/*
 * 作用：未完整交易处理   如果当前的卡号在交易记录中有未结算交易记录则调用该函数并提示结算
 * record是需要UI填充的相关信息，该信息可从交易记录获取
 * 成功返回0 ,成功时会返回TAC  UI需更新交易记录
 * 失败原因 1无对应记录  3(未感应到卡片)   5读卡器故障  其他刷卡返回失败原因
 * */
int protocol_yct_card_incomplete_settle(yct_incomplete_trade* record, unsigned char tac[4]);

/*
 * 作用：捕捉黑名单  如果当前读到的卡号在黑名单中存在，则调用该函数，将卡片设置为黑名单卡
 *成功返回0
 *失败原因   1卡片置黑名单报错  3(未感应到卡片)  5读卡器故障
 * */
int protocol_yct_card_catch_blacklist();

/*
 * 羊城通卡初始化，由UI传送给读卡器库设置psam和设备号 在串口初始化后调用
 * */
int protocol_yct_card_set_info(char psam[6], char devNum[8]);


//退出寻卡状态
int protocol_exit_seek_card_status(void);


#ifdef __cplusplus
}
#endif

#endif
